import os

from django import forms
from django.conf import settings
from django.contrib import admin
from django.db.models import TextField
from django.forms.models import ModelFormMetaclass
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _

from langutils import modify_class_attrs
import widgets

def create_advanced_admin_form(form_model, mix=None, visual_editor=()):
    class FormBase(ModelFormMetaclass):
        def __new__(cls, name, bases, attrs):
            for field in form_model._meta.fields:
                fclass = field.__class__.__name__
                fieldattrs = {
                    'label': capfirst(field.verbose_name),
                    'required': not field.blank,
                }

                if fclass == 'ImageField':
                    fieldattrs['widget'] = widgets.AdminImageWidget()
                    attrs[field.name] = forms.ImageField(**fieldattrs)
                elif fclass == 'FileField':
                    fieldattrs['widget'] = widgets.AdminFileWidget()
                    attrs[field.name] = forms.FileField(**fieldattrs)
                elif field.name in visual_editor:
                    fieldattrs['widget'] = widgets.VisualEditorWidget()
                    attrs[field.name] = forms.CharField(**fieldattrs)

                if mix:
                    attrs.update(mix.__dict__)

            return super(FormBase, cls).__new__(cls, name, bases, attrs)

    class Form(forms.ModelForm):
        __metaclass__ = FormBase
        class Meta:
            model = form_model

    return Form



class AdvancedAdminMetaclass(admin.options.forms.MediaDefiningClass):
    def __new__(wrappercls, wrappername, wrapperbases, wrapperattrs):
        if wrappername in ('AdvancedAdmin',):
            return super(AdvancedAdminMetaclass, wrappercls).__new__(wrappercls, wrappername, wrapperbases, wrapperattrs)

        #print wrappername, wrapperbases
        if not 'model' in wrapperattrs:
            raise Exception, 'Admin class must have `model` field! (cls=%s)' % wrappercls

        model = wrapperattrs['model']
        visual_editor = wrapperattrs.get('visual_editor', ())

        bases_attrs = {}
        for base in wrapperbases:
            if base == AdvancedAdmin: continue
            bases_attrs.update(base.__dict__)

        def mix_attrs(attrs):
            result = {}
            result.update(bases_attrs)
            result.update(attrs)
            result.update(wrapperattrs)
            result['form'] = create_advanced_admin_form(model, visual_editor=visual_editor)
            return result

        ModelAdmin = modify_class_attrs(admin.ModelAdmin, mix_attrs)
        admin.site.register(model, ModelAdmin)

        return ModelAdmin

class AdvancedAdmin:
    __metaclass__ = AdvancedAdminMetaclass

# rebranding
DjwheelAdmin = AdvancedAdmin

def create_preview_field(description, image_field_name, descr_field_name=None,
    max_size=None
):
    from django.utils.encoding import smart_unicode, smart_str, force_unicode
    def field(self):
        image_field = getattr(self, image_field_name)
        if not image_field:
            return ''
        descr = descr_field_name and getattr(self, descr_field_name) or ''
        if max_size and (image_field.width, image_field.height) > max_size:
            return u'<a href="%s">%s: %dx%d</a>' % (image_field.url,
                _('big image'), image_field.width, image_field.height)
        else:
            return u'<img src="%s" width="%d" height="%d" alt="%s"/>' % \
                (image_field.url, image_field.width, image_field.height, descr)
    field.short_description = description
    field.allow_tags = True
    return field

def create_link_field(description, file_field_name, descr_field_name=None):
    def field(self):
        file_field = getattr(self, file_field_name)
        return file_field.url
    field.short_description = description
    return field

def unix_path(str):
    return unicode(str).replace('\\', '/')


from django.http import Http404
from django.core.exceptions import PermissionDenied

def get_object_with_change_permissions(self, request, model, obj_pk):
    ''' Helper function that returns a menu/menuitem if it exists
    and if the user has the change permissions '''
    try:
        obj = model._default_manager.get(pk=obj_pk)
    except model.DoesNotExist:
        # Don't raise Http404 just yet, because we haven't checked
        # permissions yet. We don't want an unauthenticated user to be able
        # to determine whether a given object exists.
        obj = None
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    if obj is None:
        raise Http404('%s object with primary key %r does not exist.' % (model.__name__, escape(obj_pk)))
    return obj
